import intl from 'react-intl-universal';
import React from 'react';
import localeData from '@/i18n/localeData';
import Cookies from 'js-cookie';
import { ConfigProvider } from '@alicloudfe/components';
import enUS from '@alicloudfe/components/lib/locale/en-us';
import zhCN from '@alicloudfe/components/lib/locale/zh-cn';
import config from './config';

const uiComponentsLocales = {
  enUS,
  zhCN,
};

const cookieLocaleKey = 'DEFAULT_LANG';
const browserLocaleKey = 'language';

class AtomIntl {
  static intl = null;
  static localeData = localeData;
  static supportedLocals = {
    localeEnUS: 'en-US',
    localeZhCN: 'zh-CN',
  };
  static COMMON_LOCALE_DATA = {
    'en-US': {
      LANG: 'English',
    },
    'zh-CN': {
      LANG: '中文',
    },
  };
  static localeMap = {
    // en
    en: AtomIntl.supportedLocals.localeEnUS,
    en_US: AtomIntl.supportedLocals.localeEnUS,
    'en-US': AtomIntl.supportedLocals.localeEnUS,
    // zh
    zh_CN: AtomIntl.supportedLocals.localeZhCN,
    'zh-CN': AtomIntl.supportedLocals.localeZhCN,
    zh: AtomIntl.supportedLocals.localeZhCN,
  };
  static init() {
    AtomIntl.intl = intl;
    window.__AtomIntl = AtomIntl;
    const locale = AtomIntl.determineLocale() || AtomIntl.supportedLocals.localeEnUS; // 兜底英文
    AtomIntl.intl.init({
      currentLocale: locale,
      locales: AtomIntl.COMMON_LOCALE_DATA,
      fallbackLocale: AtomIntl.supportedLocals.localeZhCN,
    });
    if (localeData) {
      AtomIntl.intl.load(localeData);
    }
    return AtomIntl.intl;
  }
  static determineLocale() {
    return AtomIntl.getTemporaryLocale()
      || AtomIntl.getCookieLocale()
      || AtomIntl.getBrowserLocale() || '';
  }
  static getIntlInstance() {
    if (!window.__AtomIntl) {
      return AtomIntl.init();
    } else {
      AtomIntl.intl = window.__AtomIntl.intl;
      if (localeData) {
        AtomIntl.intl.load(localeData);
      }
      return window.__AtomIntl.intl;
    }
  }
  static get(...args) {
    return AtomIntl.getIntlInstance().get(...args);
  }
  static getInitOptions() {
    return AtomIntl.getIntlInstance().getInitOptions();
  }
  /**
   * 获取当前所有的语言配置信息。
   */
  static getCurrentLocales() {
    const currentOptions = AtomIntl.getInitOptions();
    const { locales } = currentOptions;
    return locales;
  }
  /**
   * 获取当前语言。如：zh-CN
   * @returns {string} zh-CN or en-US
   */
  static getCurrentLocale() {
    const currentOptions = AtomIntl.getInitOptions();
    const { currentLocale } = currentOptions;
    return currentLocale || AtomIntl.supportedLocals.localeEnUS;
  }
  static setLang(locale) {
    if (!locale) {
      // eslint-disable-next-line no-console
      console.warn('You need pass an locale to set language.');
      return;
    }
    // 设置 Cookie
    AtomIntl.saveCookieLocale(locale);
    AtomIntl.saveTemporaryLocale(locale);
    window.location.reload();
  }
  static load(locales) {
    AtomIntl.getIntlInstance().load(locales);
  }
  static isChineseLocale() {
    return AtomIntl.getCurrentLocale() === AtomIntl.supportedLocals.localeZhCN;
  }
  static switchChineseAndEnglish(value) {
    AtomIntl.setLang(value ? AtomIntl.supportedLocals.localeZhCN : AtomIntl.supportedLocals.localeEnUS);
  }

  static getBrowserLocale() {
    return AtomIntl.localeMap[navigator.language];
  }

  static saveCookieLocale(locale) {
    Cookies.set(cookieLocaleKey, locale.replace(/-/g, '_'), { domain: config.cookiePrefix });
  }
  static getCookieLocale() {
    return AtomIntl.localeMap[Cookies.get(cookieLocaleKey)];
  }

  static saveTemporaryLocale(locale) {
    localStorage.setItem(browserLocaleKey, locale);
  }
  static getTemporaryLocale() {
    return localStorage.getItem(browserLocaleKey);
  }
  static removeTemporaryLocale() {
    return localStorage.removeItem(browserLocaleKey);
  }

  static ConfigProvider(props) {
    const {
      children,
      ...others
    } = props;
    const currentLocale = AtomIntl.getCurrentLocale();
    const locale = uiComponentsLocales[currentLocale.replace('-', '')];
    return (
      <ConfigProvider locale={locale} {...others}>
        {children}
      </ConfigProvider>
    );
  }
}

export default AtomIntl;
